-
Notifications
You must be signed in to change notification settings - Fork 356
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Replace provision Tagging tree by component #5550
Replace provision Tagging tree by component #5550
Conversation
@miq-bot add_label WIP |
b0f1698
to
3f7100c
Compare
@miq-bot add_label tagging |
3f7100c
to
4e71039
Compare
@miq-bot remove_label wip |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You have a few antipatterns, please address them.
const params = {id: store.getState().tagging.appState.affectedItems[0], cat: tag.tagCategory.id, val: tag.tagValue.id, check: 1, tree_typ: 'tags' }; | ||
const ids = [...store.getState().tagging.appState.assignedTags.map( t => t.values.map(val => val.id)), tag.tagValue.id].flat(); | ||
console.log(ids); | ||
const params = (meta.type === 'provision' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a 🦛 step backwards 🦛 with the ternary operator... 🔴 🏴 @himdel @martinpovolny @Hyperkid123 any idea how else we could do this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What do you mean by step back?
There are not many options with expression like this. You can do classic if
statement. Or switch
or maybe invoke a function like this:
// or extract it somewhere as a helper function
params = ((type, state) => ({
provision: state.something...,
default: 'b'
})[type || 'default'])(meta.type, state)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My problem here is the special case when the tagging is on the provisioning screen. Anything like this has the potential to grow into a huge case with a ton of exceptions
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah ok, i would suggest then to add a Prop to components that are using this and create the params inside the component and send it as a (meta)parameter to the action. We have the thunk middleware so we can get to the current state inside action creators almost exactly the same way as in middleware.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There should be a convention for this.
Every form not just talking to the API will have the same problem - the definiton of what to send via http can not be part of the component itself.
Passing a function to transform state to request data sounds reasonable, but maybe we should really do it the same way in all the react forms.
@@ -5,7 +5,12 @@ import promiseMiddleware from 'redux-promise-middleware'; | |||
export const taggingMiddleware = store => next => action => { | |||
const { type, meta, tagCategory, tag } = action; | |||
if (meta && meta.url) { | |||
const params = {id: store.getState().tagging.appState.affectedItems[0], cat: tag.tagCategory.id, val: tag.tagValue.id, check: 1, tree_typ: 'tags' }; | |||
const ids = [...store.getState().tagging.appState.assignedTags.map( t => t.values.map(val => val.id)), tag.tagValue.id].flat(); | |||
console.log(ids); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Probably not wanted
end | ||
|
||
assignments = Classification.select { |tag| vm_tags.include?(tag.id) } | ||
assigned_tags = Classification.select { |tag| vm_tags.include?(tag.id) }.map do |tag| |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why are you duplicating code here?
@ci_node[:children] = @ci_kids if @ci_kids.present? | ||
all_tags.push(@ci_node) if @ci_kids.present? | ||
# for some reason @tags is set in wf, and it is changed by map bellow which causes bugs | ||
wf.instance_variable_set(:@tags, nil) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What's wf? If it is undocumented behavior, please look it up and document it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
stands for workflow, used a lot in automate code (309 occurences)
:save_url => '', | ||
:cancel_url => '' | ||
} | ||
@tags1 = {:tags => tags, :assignedTags => assigned_tags, :affectedItems => []} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why @tags1
? Why not 42?
end | ||
@all_tags_tree = TreeBuilder.convert_bs_tree(all_tags).to_json # Add ci node array to root of tree | ||
tags = tags.map { |t| {:id => t[:name], :singleValue => t[:single_value] }.merge(t) } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You have better hash manipulation techniques for this, check out the documentation
end | ||
@all_tags_tree = TreeBuilder.convert_bs_tree(all_tags).to_json # Add ci node array to root of tree | ||
tags = tags.map { |t| {:id => t[:name], :singleValue => t[:single_value] }.merge(t) } | ||
tags.map do |t| |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not very happy about the map
here, maybe each
. Or map!
and do the delete properly.
380c263
to
e198f1d
Compare
:locals => {:tree_id => "all_tags_treebox", | ||
:tree_name => "all_tags_tree", | ||
:bs_tree => @all_tags_tree, | ||
:oncheck => "miqOnCheckProvTags", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
also remove the miqOnCheckProvTags
function please (and from the whitelist)?
(If it was used miq_prov_vars
would still need the split .. but it is dead now :).)
# for some reason @tags is set in wf, and it is changed by map bellow which causes bugs | ||
wf.instance_variable_set(:@tags, nil) | ||
tags = wf.allowed_tags | ||
tags.each do |cat| |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Something like
tags = wf.allowed_tags.map do |cat|
{
:values => cat[:children].map do |tag|
{:id => tag.first, :description => tag.second[:description]}
end,
:id => cat[:name],
:singleValue => cat[:single_value],
}
end
would probably be better than overwriting items in the allowed_tags array?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In general please prefer functional style over each :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, I was stuck with an idea, that I need to modify existing hash....while create a new is much nicer
end.uniq | ||
|
||
@button_urls = { | ||
:save_url => '', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks suspicious.. you're never saving or cancelling?
(Maybe just a comment why?)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It shouldn't be there...
@@ -5,10 +5,11 @@ import promiseMiddleware from 'redux-promise-middleware'; | |||
export const taggingMiddleware = store => next => action => { | |||
const { type, meta, tagCategory, tag } = action; | |||
if (meta && meta.url) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
switch (type) {
case 'UI-COMPONENTS_TAGGING_TOGGLE_TAG_VALUE_CHANGE':
$.post(meta.url, meta.params(meta.type, store.getState(), tag));
break;
case 'UI-COMPONENTS_TAGGING_DELETE_ASSIGNED_TAG':
$.post(meta.url, meta.onDelete(meta.type, params, tag.tagValue.id));
break;
}
and move that check: 0
to onDelete definition?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Or ideally call the same method, since you're passing the type anyway. (type != meta.type, sorry)
The point is, there should be only 1 place dealing with this logic, not 2, or 3.
(maybe onDelete should not take computed params, and do it by itself, from state, that way maybe you can also unify the args)
@PanSpagetka please avoid using commit messages that lack context, having the "code styling" commit in the master's git log will be totally useless for the future 😕 |
052379f
to
af03282
Compare
ping @terezanovotna |
@@ -290,26 +289,20 @@ | |||
= field_hash[:notes] | |||
- elsif [:tag_ids, :vm_tags].include?(field) | |||
-# tree control for tags fields | |||
.col-md-8 | |||
.col-md-10 | |||
#all_tags_treebox.treeview-pf-hover.treeview-pf-select{:style => "color:#000; overflow: hidden;"} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should probably remove these tree classes and style overrides since this is no longer a tree.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, the div is actually empty, and the code setting check
is not used anymore, so you can just remove lines 293 to 299
3 more remnants of the tree:
|
Also looks like this will still need a react-ui-components update:
(I don't think the component should ever expect |
When changing a tag from one of the "only a single value" categories:
the UI shows Category: Bar on the right, sends
Note that the first tag id remained in the second request, so we're sending 2 tags from a "single tag only" category. EDIT: this works in conjunction with the backend discarding all but the last id in each single-value category .. and the last chosen will be last simply because it's added to the list last .. and the client state gets updated by the server state on every change. I think this works :) |
4f868a0
to
4b2a2f8
Compare
4b2a2f8
to
b467f54
Compare
(
) |
b467f54
to
1bd910a
Compare
@@ -1013,7 +1013,7 @@ def build_tags_tree(wf, vm_tags, edit_mode) | |||
end | |||
} | |||
end.uniq | |||
|
|||
# assigned_tags.map! { |c| c[:values].delete_if {|v| v[:id] == params[:deleted].to_i} } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Probably want to delete this?
@@ -21,7 +21,7 @@ const params = (type = 'default', state, tag = {}) => ({ | |||
})[type] | |||
|
|||
const onDelete = (type = 'default', params = [], deleted_element) => ({ | |||
provision: {...params, check: 0, ids_checked: params.ids_checked.filter(element => element !== deleted_element)}, | |||
provision: {...params, check: 0, ids_checked: params.ids_checked.filter(element => element !== deleted_element), deleted: deleted_element }, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess sending deleted
no longer matters?
The spec failures look relevant, the post is called with different params now so the test is wrong. |
Checked commits PanSpagetka/manageiq-ui-classic@f7abada~...2ce52a3 with ruby 2.4.6, rubocop 0.69.0, haml-lint 0.20.0, and yamllint 1.10.0 |
LGTM, merging :) @PanSpagetka One thing that needs fixing - as a separate PR - we should never be using numeric ids in javascript. Due to the limitation of Can you change that plase? |
Great! Are there any further places where we need the new tagging component? |
Yes, two of them, @PanSpagetka already working on them. |
Replace provision Tagging tree with a new component
Links [Optional]
#5515
Screenshot
Steps for Testing/QA [Optional]
Provision VM/Instance -> Purpose tab